package com.approval.service;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.approval.dto.CompleteTaskRequest;
import com.approval.dto.StartProcessRequest;
import com.approval.dto.UserResponse;
import com.approval.entity.ApprovalInstance;
import com.approval.entity.ApprovalProcess;
import com.approval.entity.ApprovalTask;
import com.approval.entity.User;
import com.approval.exception.BusinessException;
import com.approval.mapper.ApprovalInstanceMapper;
import com.approval.mapper.ApprovalProcessMapper;
import com.approval.mapper.ApprovalTaskMapper;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ApprovalInstanceService {
    
    @Autowired
    private ApprovalInstanceMapper instanceMapper;
    
    @Autowired
    private ApprovalTaskMapper taskMapper;
    
    @Autowired
    private ApprovalProcessMapper processMapper;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private TaskService taskService;
    
    @Transactional
    public ApprovalInstance startProcess(StartProcessRequest request) {
        User currentUser = userService.getCurrentUser();
        ApprovalProcess process = processMapper.selectById(request.getProcessId());
        
        if (process == null) {
            throw new BusinessException("流程不存在");
        }
        
        if (process.getProcessKey() == null || process.getProcessKey().trim().isEmpty()) {
            throw new BusinessException("流程未配置流程Key，无法启动");
        }
        
        // 启动Flowable流程实例
        Map<String, Object> variables = new HashMap<>();
        variables.put("applicantId", currentUser.getId());
        variables.put("applicantName", currentUser.getName());
        variables.put("title", request.getTitle());
        
        // 处理表单数据
        String content = "";
        if (request.getFormData() != null && !request.getFormData().isEmpty()) {
            try {
                content = new ObjectMapper().writeValueAsString(request.getFormData());
            } catch (Exception e) {
                content = request.getFormData().toString();
            }
        } else if (request.getContent() != null) {
            content = request.getContent();
        }
        variables.put("content", content);
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
            process.getProcessKey(), variables);
        
        // 创建审批实例
        ApprovalInstance instance = new ApprovalInstance();
        instance.setProcessId(request.getProcessId());
        instance.setProcessInstanceId(processInstance.getId());
        instance.setTitle(request.getTitle());
        instance.setContent(content);
        instance.setApplicantId(currentUser.getId());
        instance.setApplicantName(currentUser.getName());
        instance.setStatus("RUNNING");
        instance.setCreateTime(new Date());
        instance.setUpdateTime(new Date());
        
        instanceMapper.insert(instance);
        
        // 创建第一个任务
        List<Task> tasks = taskService.createTaskQuery()
            .processInstanceId(processInstance.getId())
            .list();
        
        if (!tasks.isEmpty()) {
            Task task = tasks.get(0);
            ApprovalTask approvalTask = new ApprovalTask();
            approvalTask.setInstanceId(instance.getId());
            approvalTask.setTaskId(task.getId());
            approvalTask.setTaskName(task.getName());
            approvalTask.setAssigneeId(Long.valueOf(task.getAssignee()));
            approvalTask.setStatus("PENDING");
            approvalTask.setCreateTime(new Date());
            approvalTask.setUpdateTime(new Date());
            
            taskMapper.insert(approvalTask);
        }
        
        return instance;
    }
    
    @Transactional
    public void completeTask(CompleteTaskRequest request) {
        ApprovalTask approvalTask = taskMapper.selectById(request.getTaskId());
        if (approvalTask == null) {
            throw new BusinessException("任务不存在");
        }
        
        if (!"PENDING".equals(approvalTask.getStatus())) {
            throw new BusinessException("任务已完成");
        }
        
        // 完成Flowable任务
        Map<String, Object> variables = new HashMap<>();
        variables.put("approved", request.getApproved());
        variables.put("comment", request.getComment());
        
        taskService.complete(request.getTaskId().toString(), variables);
        
        // 更新审批任务
        approvalTask.setComment(request.getComment());
        approvalTask.setStatus(request.getApproved() ? "APPROVED" : "REJECTED");
        approvalTask.setUpdateTime(new Date());
        
        taskMapper.update(approvalTask);
        
        // 检查流程是否结束
        ApprovalInstance instance = instanceMapper.selectById(approvalTask.getInstanceId());
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
            .processInstanceId(instance.getProcessInstanceId())
            .singleResult();
        
        if (processInstance == null) {
            // 流程已结束
            instance.setStatus(request.getApproved() ? "APPROVED" : "REJECTED");
            instance.setUpdateTime(new Date());
            instanceMapper.update(instance);
        } else {
            // 流程继续，创建下一个任务
            List<Task> nextTasks = taskService.createTaskQuery()
                .processInstanceId(instance.getProcessInstanceId())
                .list();
            
            for (Task nextTask : nextTasks) {
                ApprovalTask nextApprovalTask = new ApprovalTask();
                nextApprovalTask.setInstanceId(instance.getId());
                nextApprovalTask.setTaskId(nextTask.getId());
                nextApprovalTask.setTaskName(nextTask.getName());
                nextApprovalTask.setAssigneeId(Long.valueOf(nextTask.getAssignee()));
                nextApprovalTask.setStatus("PENDING");
                nextApprovalTask.setCreateTime(new Date());
                nextApprovalTask.setUpdateTime(new Date());
                
                taskMapper.insert(nextApprovalTask);
            }
        }
    }
    
    public List<ApprovalInstance> getMyApplications() {
        User currentUser = userService.getCurrentUser();
        return instanceMapper.selectByUserId(currentUser.getId());
    }
    
    public List<Map<String, Object>> getMyTasks() {
        User currentUser = userService.getCurrentUser();
        List<ApprovalTask> tasks = taskMapper.selectByUserId(currentUser.getId());
        return tasks.stream()
            .filter(task -> "PENDING".equals(task.getStatus()))
            .map(this::convertTaskToMap)
            .collect(Collectors.toList());
    }
    
    public List<Map<String, Object>> getMyCompletedTasks() {
        User currentUser = userService.getCurrentUser();
        List<ApprovalTask> tasks = taskMapper.selectByUserId(currentUser.getId());
        return tasks.stream()
            .filter(task -> "COMPLETED".equals(task.getStatus()))
            .map(this::convertTaskToMap)
            .collect(Collectors.toList());
    }
    
    public ApprovalInstance getInstanceById(Long id) {
        ApprovalInstance instance = instanceMapper.selectById(id);
        if (instance == null) {
            throw new BusinessException("审批实例不存在");
        }
        
        List<ApprovalTask> tasks = taskMapper.selectByInstanceId(id);
        instance.setTasks(tasks);
        
        return instance;
    }
    
    public void cancelInstance(Long id) {
        ApprovalInstance instance = instanceMapper.selectById(id);
        if (instance == null) {
            throw new BusinessException("审批实例不存在");
        }
        
        if (!"RUNNING".equals(instance.getStatus())) {
            throw new BusinessException("只能取消运行中的审批实例");
        }
        
        // 终止Flowable流程实例
        runtimeService.deleteProcessInstance(instance.getProcessInstanceId(), "用户取消");
        
        // 更新审批实例状态
        instance.setStatus("CANCELLED");
        instance.setUpdateTime(new Date());
        instanceMapper.update(instance);
        
        // 更新所有待处理任务状态
        List<ApprovalTask> pendingTasks = taskMapper.selectByInstanceId(id);
        for (ApprovalTask task : pendingTasks) {
            if ("PENDING".equals(task.getStatus())) {
                task.setStatus("CANCELLED");
                task.setUpdateTime(new Date());
                taskMapper.update(task);
            }
        }
    }
    
    public ApprovalTask getTaskById(Long taskId) {
        ApprovalTask task = taskMapper.selectById(taskId);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        return task;
    }
    
    public void delegateTask(Long taskId, Long delegateUserId) {
        ApprovalTask approvalTask = taskMapper.selectById(taskId);
        if (approvalTask == null) {
            throw new BusinessException("任务不存在");
        }
        
        if (!"PENDING".equals(approvalTask.getStatus())) {
            throw new BusinessException("只能委托待处理的任务");
        }
        
        // 委托Flowable任务
        taskService.delegateTask(approvalTask.getTaskId(), delegateUserId.toString());
        
        // 更新审批任务
        approvalTask.setAssigneeId(delegateUserId);
        approvalTask.setUpdateTime(new Date());
        taskMapper.update(approvalTask);
    }
    
    // 辅助方法：将UserResponse转换为User
    private User convertUserResponseToUser(UserResponse userResponse) {
        if (userResponse == null) {
            return null;
        }
        
        User user = new User();
        user.setId(userResponse.getId());
        user.setUsername(userResponse.getUsername());
        user.setName(userResponse.getName());
        user.setEmail(userResponse.getEmail());
        user.setPhone(userResponse.getPhone());
        user.setStatus(userResponse.getStatus());
        user.setCreateTime(userResponse.getCreateTime());
        user.setUpdateTime(userResponse.getUpdateTime());
        
        return user;
    }
    
    // 获取实例详情
    public Map<String, Object> getInstanceDetail(Long instanceId) {
        ApprovalInstance instance = instanceMapper.selectById(instanceId);
        if (instance == null) {
            throw new BusinessException("审批实例不存在");
        }
        
        Map<String, Object> detail = new HashMap<>();
        detail.put("instance", instance);
        
        // 获取任务列表
        List<ApprovalTask> tasks = taskMapper.selectByInstanceId(instanceId);
        detail.put("tasks", tasks);
        
        // 获取流程信息
        ApprovalProcess process = processMapper.selectById(instance.getProcessId());
        detail.put("process", process);
        
        return detail;
    }
    
    // 转交任务
    public void transferTask(Long taskId, Long targetUserId, String reason) {
        ApprovalTask task = taskMapper.selectById(taskId);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        
        if (!"PENDING".equals(task.getStatus())) {
            throw new BusinessException("只能转交待处理的任务");
        }
        
        // 更新任务转交人
        task.setAssigneeId(targetUserId);
        task.setUpdateTime(new Date());
        taskMapper.update(task);
        
        // 转交Flowable任务
        taskService.setAssignee(task.getTaskId(), targetUserId.toString());
    }
    
    // 批量完成任务
    public void batchCompleteTask(List<Long> taskIds, String action, String comment) {
        for (Long taskId : taskIds) {
            CompleteTaskRequest request = new CompleteTaskRequest();
            request.setTaskId(taskId);
            request.setAction(action);
            request.setComment(comment);
            request.setApproved("approve".equals(action));
            completeTask(request);
        }
    }
    
    // 将ApprovalTask转换为Map
    private Map<String, Object> convertTaskToMap(ApprovalTask task) {
        Map<String, Object> taskMap = new HashMap<>();
        taskMap.put("id", task.getId());
        taskMap.put("taskId", task.getTaskId());
        taskMap.put("instanceId", task.getInstanceId());
        taskMap.put("assigneeId", task.getAssigneeId());
        taskMap.put("taskName", task.getTaskName());
        taskMap.put("status", task.getStatus());
        taskMap.put("comment", task.getComment());
        taskMap.put("createTime", task.getCreateTime());
        taskMap.put("updateTime", task.getUpdateTime());
        return taskMap;
    }
    
    /**
     * 根据流程ID和状态查询实例
     */
    public List<ApprovalInstance> getInstancesByProcessIdAndStatus(Long processId, String status) {
        return instanceMapper.selectByProcessIdAndStatus(processId, status);
    }
}